using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

using OrderService.Application.Dtos;
using OrderService.Application.Services;
using OrderService.Domain.Events;
using OrderService.Domain.Models;
using OrderService.Domain.Repositories;
using SharedKernel.Infrastructure.EventBus;

namespace OrderService.Application.Services
{
    /// <summary>
    /// 订单应用服务实现
    /// </summary>
    public class OrderAppService : IOrderAppService
    {
        private readonly IOrderRepository _orderRepository;
        private readonly IEventBus _eventBus;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="orderRepository">订单仓储</param>
        /// <param name="eventBus">事件总线</param>
        public OrderAppService(IOrderRepository orderRepository, IEventBus eventBus)
        {
            _orderRepository = orderRepository;
            _eventBus = eventBus;
        }

        /// <summary>
        /// 创建订单
        /// </summary>
        /// <param name="request">创建订单请求</param>
        /// <returns>订单ID</returns>
        public async Task<Guid> CreateOrderAsync(CreateOrderRequest request)
        {
            // 转换订单项请求为领域模型
            var orderItems = request.Items.Select(item => OrderItem.Create(
                item.ProductId,
                item.ProductName,
                item.UnitPrice,
                item.Quantity
            )).ToList();

            // 创建订单
            var order = Order.Create(request.CustomerId, orderItems);
            order.ShippingAddress = request.ShippingAddress;
            order.PhoneNumber = request.PhoneNumber;
            await _orderRepository.InsertAsync(order);

            // 发布领域事件
            foreach (var domainEvent in order.DomainEvents)
            {
                await _eventBus.PublishAsync(domainEvent);
            }

            order.ClearDomainEvents();
            return order.Id;
        }

        /// <summary>
        /// 获取订单
        /// </summary>
        /// <param name="id">订单ID</param>
        /// <returns>订单响应模型</returns>
        public async Task<OrderResponse> GetOrderAsync(Guid id)
        {
            var order = await _orderRepository.SingleAsync(id);
            if (order == null)
                return null;

            return MapToResponse(order);
        }

        /// <summary>
        /// 获取订单（按订单编号）
        /// </summary>
        /// <param name="orderNumber">订单编号</param>
        /// <returns>订单响应模型</returns>
        public async Task<OrderResponse> GetOrderByNumberAsync(string orderNumber)
        {
            var order = await _orderRepository.GetByOrderNumberAsync(orderNumber);
            if (order == null)
                return null;

            return MapToResponse(order);
        }

        /// <summary>
        /// 获取客户的所有订单
        /// </summary>
        /// <param name="customerId">客户ID</param>
        /// <returns>订单响应模型列表</returns>
        public async Task<List<OrderResponse>> GetOrdersByCustomerAsync(Guid customerId)
        {
            var orders = await _orderRepository.GetByCondition(o => o.CustomerId == customerId).ToListAsync();
            return orders.Select(MapToResponse).ToList();
        }

        /// <summary>
        /// 更新订单状态
        /// </summary>
        /// <param name="id">订单ID</param>
        /// <param name="status">订单状态</param>
        /// <param name="remark">备注</param>
        public async Task UpdateOrderStatusAsync(Guid id, string status, string remark = null)
        {
            var order = await _orderRepository.SingleAsync(id);
            if (order == null)
                throw new KeyNotFoundException($"订单不存在: {id}");

            // 转换字符串状态为枚举
            if (!Enum.TryParse<OrderStatus>(status, true, out var orderStatus))
                throw new ArgumentException($"无效的订单状态: {status}");

            // 更新订单状态
            order.UpdateStatus(orderStatus);
            order.Remark = remark;
            await _orderRepository.UpdateAsync(order);

            // 发布订单状态变更事件
            await _eventBus.PublishAsync(new OrderStatusChangedEvent(order, orderStatus, remark));
        }

        /// <summary>
        /// 取消订单
        /// </summary>
        /// <param name="id">订单ID</param>
        public async Task CancelOrderAsync(Guid id)
        {
            var order = await _orderRepository.SingleAsync(id);
            if (order == null)
                throw new KeyNotFoundException($"订单不存在: {id}");

            order.Cancel();
            await _orderRepository.UpdateAsync(order);

            // 发布订单取消事件
            await _eventBus.PublishAsync(new OrderCancelledEvent(order));
        }

        /// <summary>
        /// 将订单实体映射为响应模型
        /// </summary>
        /// <param name="order">订单实体</param>
        /// <returns>订单响应模型</returns>
        private OrderResponse MapToResponse(Order order)
        {
            return new OrderResponse
            {
                Id = order.Id,
                OrderNumber = order.OrderNumber,
                CustomerId = order.CustomerId,
                Status = order.Status.ToString(),
                TotalAmount = order.TotalAmount,
                ShippingAddress = order.ShippingAddress,
                PhoneNumber = order.PhoneNumber,
                CreatedAt = order.CreatedAt,
                UpdatedAt = order.UpdatedAt,
                Items = order.Items.Select(item => new OrderItemResponse
                {
                    Id = item.Id,
                    ProductId = item.ProductId,
                    ProductName = item.ProductName,
                    Quantity = item.Quantity,
                    UnitPrice = item.UnitPrice,
                    Subtotal = item.LineTotal
                }).ToList()
            };
        }
    }
}